package com.gzsxy.esjy.message.netty.decoder;


import com.gzsxy.esjy.message.channel.ChannelManager;
import com.gzsxy.esjy.message.netty.Message;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.handler.codec.http.websocketx.*;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.Charset;
import java.util.List;

/**
 *  解码器 MessageToMessageDecoder 将符合条件的一种类型数据转成另一种类型数据。
 * @author zhangxiaolong
 *
 */
@Slf4j
public class WebsocketDecoder extends MessageToMessageDecoder<WebSocketFrame>{

	private final WebSocketServerHandshaker handshaker ;
	
	public WebsocketDecoder(WebSocketServerHandshaker handshaker) {
		super();
		this.handshaker = handshaker;
	}

	@Override
	protected void decode(ChannelHandlerContext ctx, WebSocketFrame msg, List<Object> out) throws Exception {
		//响应底层心跳
		if(msg instanceof PingWebSocketFrame) {
			log.info("接收到来自于 {} 的[esjy]心跳信息 ",ctx.channel().attr(ChannelManager.IP).get());
			ctx.writeAndFlush(new PongWebSocketFrame()) ;
			return ;
		}
		//获取客户端的响应心跳:不做任何处理
		if(msg instanceof PongWebSocketFrame) {
			log.info("接收到来自于 {} 的[esjy]心跳响应 ",ctx.channel().attr(ChannelManager.IP).get());
			return ;
		}
		//关闭事件
		if(msg instanceof CloseWebSocketFrame) {
			log.info("接收到来自于 {} 的关闭连接指令 ",ctx.channel().attr(ChannelManager.IP).get());
			handshaker.close(ctx.channel(), (CloseWebSocketFrame) msg.retain());
			return ;
		}
		
		 // 阻止二进制报文
        if (!(msg instanceof TextWebSocketFrame)) {
        	UnsupportedOperationException unsupportedOperationException = new UnsupportedOperationException(String.format(
                    "%s frame types not supported", msg.getClass().getName()));
            log.error(unsupportedOperationException.getMessage(), unsupportedOperationException);
            throw unsupportedOperationException;
        }
        //获取内容
        String text = msg.content().toString(Charset.defaultCharset()) ;
        //空报文，视为心跳
        if("".equals(text)) {
        	log.info("接收到来自于 {} 的[应用]心跳信息 ",ctx.channel().attr(ChannelManager.IP).get());
        	ctx.writeAndFlush(new TextWebSocketFrame()) ;
        	return ;
        }
		Object builder = decode(text);
		if(builder != null) {
			//放入下一个handler处理
			out.add(builder) ;
		}

	}

	/**
	 * 报文解析
	 * @param request
	 * @return
	 */
	protected Object decode(String request){
		return Message.builder(request);
	}
	
}

